﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.UI;
using UnityEngine.Events;
using System;

/// <summary>
/// 点击平面进行的操作
/// 1. 添加视频
/// 2. 添加模型
/// 3. 添加图片
/// </summary>
[RequireComponent(typeof(ARRaycastManager))]
public class PlaneController : MonoBehaviour
{
    private GameObject mTvVideoPrefab;
    private GameObject mTvVideoObject;

    private GameObject mModelPrefab;
    private GameObject mModelObject;

    private GameObject mImagePrefab;
    private GameObject mImageObject;
    private Image mImage;

    static List<ARRaycastHit> Hits;
    private ARRaycastManager mRaycastManager;
    private ARPlaneManager mARPlaneManager;
    private UnityEngine.Video.VideoPlayer mVideoPlayer;

    private int mMaxTVnumber = 1;
    private int mCurrentTVNum = 0;
    private int mMaxModelNum = 1;
    private int mCurrentModelNum = 0;
    private float AndroidAngle = 180.0f;
    private bool mIsLastMoved = false; //上次是否滑动，防止 Rotate 起始和结束同一位置导致认为是点击
    private Vector2 mLastTouchPosition; //上一次手指按下的位置
    private ResourceAddType mResourceType = ResourceAddType.VIDEO;

    private void Start()
    {
        Hits = new List<ARRaycastHit>();
        mRaycastManager = GetComponent<ARRaycastManager>();
        mARPlaneManager = GetComponent<ARPlaneManager>();
        //BtnPlay.transform.GetComponent<Button>().onClick.AddListener(() => mVideoPlayer.Play());

        mTvVideoPrefab = Resources.Load("Prefabs/TVs") as GameObject;
        mModelPrefab = Resources.Load("Prefabs/Astronaut") as GameObject;
        mImagePrefab = Resources.Load("Prefabs/Dog") as GameObject;

        mImage = GameObjectUtil.createImageWithSprite("Imgs/Dog");
    }

    void Update()
    {
        addPrefabOnClick();
    }

    private void addPrefabOnClick()
    {
        if (Input.touchCount == 0)
            return;

        var curTouch = Input.GetTouch(0);
        var curTouchPosition = curTouch.position;

        if (mRaycastManager.Raycast(curTouchPosition, Hits, TrackableType.PlaneWithinPolygon | TrackableType.PlaneWithinBounds))
        {
            if(Input.touchCount == 1) //一根手指并且是点击，手指抬起时才添加对象，防止 Rotate 时发生冲突又添加了一个对象
            {
                if (curTouch.phase == TouchPhase.Began)
                {
                    mIsLastMoved = false;
                    mLastTouchPosition = curTouch.position;
                    LogUtils.debug("curTouch.phase == TouchPhase.Began mLastTouchPosition.x = " + mLastTouchPosition.x + " mLastTouchPosition.y = " + mLastTouchPosition.y);
                }
                else if(curTouch.phase == TouchPhase.Moved)
                {
                    mIsLastMoved = true;
                }
                else if (curTouch.phase == TouchPhase.Ended)
                {
                    LogUtils.debug("curTouch.phase == TouchPhase.Ended curTouchPosition.x = " + curTouchPosition.x + " curTouchPosition.y = " + curTouchPosition.y + " mIsLastMoved = " + mIsLastMoved);
                    var isClickUI = ClickUtil.Instance.IsPointerOverUIObject(curTouchPosition); //防止点击 UI 按钮也添加对象
                    if ((!mIsLastMoved) && (mLastTouchPosition == null || isClickGesture(mLastTouchPosition, curTouchPosition) && (!isClickUI)))
                    {
                        var hitPose = Hits[0].pose;
                        switch (mResourceType)
                        {
                            case ResourceAddType.VIDEO:
                                addTvVideoPrefab(hitPose);
                                break;
                            case ResourceAddType.MODEL:
                                addModelPrefab(hitPose);
                                break;
                            case ResourceAddType.IMG:
                                addImagePrefab(hitPose);
                                break;
                        }
                    }
                }
            }
        }
    }

    //判断是不是点击，小于 20 就认为是点击
    bool isClickGesture(Vector2 lastPos, Vector2 curPos)
    {

        //var result = Mathf.Sqrt((lastPos.x - curPos.x) * (lastPos.x - curPos.x) + (lastPos.y - curPos.y) * (lastPos.y - curPos.y));
        //LogUtils.debug("PlaneController isClickGesture result= " + result);

        var xOffset = lastPos.x - curPos.x;
        var yOffset = lastPos.y - curPos.y;

        LogUtils.debug("PlaneController lastPos.x = " + lastPos.x + " lastPos.y =" + lastPos.y);
        LogUtils.debug("PlaneController curPos.x = " + curPos.x + " curPos.y =" + curPos.y);
        LogUtils.debug("PlaneController xOffset= " + xOffset + " yOffset=" + yOffset);

        return Math.Abs(xOffset) < 70 && Math.Abs(yOffset) < 70;
    }

    private void addTvVideoPrefab(Pose hitPose)
    {
        if (mTvVideoObject == null && mCurrentTVNum < mMaxTVnumber)
        {
            mTvVideoObject = Instantiate(mTvVideoPrefab, hitPose.position, hitPose.rotation);
            //spawnedObject.transform.Rotate(new Vector3(0, AndroidAngle, 0));
            mVideoPlayer = mTvVideoObject.gameObject.transform.Find("Quad").gameObject.GetComponent<UnityEngine.Video.VideoPlayer>();
            //TrunOffPlaneDetect();
            mCurrentTVNum++;
        }
        else
        {
            mTvVideoObject.transform.position = hitPose.position;
        }
    }

    /// <summary>
    /// 添加模型，暂时是只添加一个，再点击平面只是将之前添加的模型调整位置而不是再添加一个
    /// </summary>
    /// <param name="hitPose"></param>
    private void addModelPrefab(Pose hitPose)
    {
        if (mModelObject == null && mCurrentModelNum < mMaxModelNum)
        {
            ToastUtil.showToast("添加了模型");
            mModelObject = Instantiate(mModelPrefab, hitPose.position, hitPose.rotation);
            mModelObject.transform.Rotate(new Vector3(0, AndroidAngle, 0));
            mCurrentModelNum++;
        }
        else
        {
            //如果距离上次点击的点距离较近，则认为是要旋转，则不改变位置
            mModelObject.transform.position = hitPose.position;
        }
    }

    private void addImagePrefab(Pose hitPose)
    {
        ToastUtil.showToast("添加了图片 mImage= " + mImage);

        //mImage.rectTransform.SetParent(hitPose);
        //mImage.rectTransform.transform.position = hitPose.position;
        //mImage.rectTransform.transform.rotation = hitPose.rotation;
        //mImage.rectTransform.sizeDelta *= mImage.canvas.scaleFactor; //image.canvas.scaleFactor 是获取当前分辨率的缩放比，整行代码是为了分辨率适配

        mImageObject = Instantiate(mImagePrefab, hitPose.position, hitPose.rotation);
        mImageObject.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
    }

    private void TrunOffPlaneDetect()
    {
        mARPlaneManager.enabled = false;
        foreach (var plane in mARPlaneManager.trackables)
            plane.gameObject.SetActive(false);
    }

    public void OnPlayVideoBtnClick()
    {
        OperateBtnClick("播放", () =>
        {
            mVideoPlayer.Play();
        });
    }

    public void OnPauseVideoBtnClick()
    {
        OperateBtnClick("暂停", () =>
        {
            mVideoPlayer.Pause();
        });
    }

    public void OnStopVideoBtnClick()
    {
        OperateBtnClick("停止", () =>
        {
            mVideoPlayer.Stop();
        });
    }

    private void OperateBtnClick(string identifyStr, UnityAction unityAction)
    {
        if (mVideoPlayer == null)
        {
            ToastUtil.showToast("还没有添加视频!");
            return;
        }
        ToastUtil.showToast(identifyStr + "视频, mVideoPlayer.isActiveAndEnabled=" + mVideoPlayer.isActiveAndEnabled);
        if (mVideoPlayer.isActiveAndEnabled)
        {
            unityAction.Invoke();
        }
    }

    public void OnBtnTogglePlaneAddObjTypeClick()
    {
        switch (mResourceType)
        {
            case ResourceAddType.VIDEO:
                mResourceType = ResourceAddType.MODEL;
                break;
            case ResourceAddType.MODEL:
                mResourceType = ResourceAddType.IMG;
                break;
            case ResourceAddType.IMG:
                mResourceType = ResourceAddType.VIDEO;
                break;
        }
        ToastUtil.showToast("当前点击平面添加的对象类型为: " + mResourceType);
    }
}